/**
 * 更可靠的Java代码解析工具
 */
export class JavaParser {
  
  /**
   * 查找方法的完整边界，包括正确的行数计算
   */
  static findMethodBounds(content: string, methodName: string): { 
    startLine: number, 
    endLine: number,
    bodyStartLine: number,
    bodyEndLine: number,
    totalLines: number,
    nonEmptyLines: number
  } | null {
    const lines = content.split('\n');
    
    // 使用更灵活的方法签名匹配
    // 匹配: [modifiers] returnType methodName(params) [throws]
    const methodPattern = new RegExp(
      `^\\s*(?:@\\w+.*?\\n\\s*)*` + // 可选的注解（可能跨行）
      `(?:public|private|protected)?\\s*` + // 可选的访问修饰符
      `(?:static\\s+)?` + // 可选的static
      `(?:final\\s+)?` + // 可选的final
      `(?:synchronized\\s+)?` + // 可选的synchronized
      `(?:<[^>]+>\\s+)?` + // 可选的泛型返回类型
      `(?:[\\w\\<\\>,\\s\\[\\]]+\\s+)` + // 返回类型（支持泛型、数组）
      `${methodName}\\s*\\(` // 方法名和开括号
    );
    
    console.error(`[JavaParser] 开始查找方法: ${methodName}`);
    console.error(`[JavaParser] 文件总行数: ${lines.length}`);
    
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i];
      
      // 打印包含方法名的行
      if (line.includes(methodName)) {
        console.error(`[JavaParser] 在第 ${i + 1} 行找到包含方法名的行: ${line.trim()}`);
      }
      
      // 首先尝试精确匹配
      if (methodPattern.test(line)) {
        console.error(`[JavaParser] 找到方法 ${methodName} 在第 ${i + 1} 行`);
        
        // 找到方法签名的完整部分（可能跨多行）
        let signatureEndLine = i;
        let parenCount = 0;
        let foundOpenParen = false;
        
        // 查找完整的方法签名
        for (let j = i; j < lines.length; j++) {
          const currentLine = lines[j];
          for (const char of currentLine) {
            if (char === '(') {
              parenCount++;
              foundOpenParen = true;
            } else if (char === ')') {
              parenCount--;
              if (foundOpenParen && parenCount === 0) {
                signatureEndLine = j;
                break;
              }
            }
          }
          if (foundOpenParen && parenCount === 0) break;
        }
        
        // 查找方法体的开始（第一个{）
        let bodyStartLine = -1;
        let braceCount = 0;
        for (let j = signatureEndLine; j < lines.length; j++) {
          if (lines[j].includes('{')) {
            bodyStartLine = j;
            break;
          }
          // 如果遇到分号，说明是抽象方法
          if (lines[j].includes(';')) {
            return {
              startLine: i + 1,
              endLine: j + 1,
              bodyStartLine: -1,
              bodyEndLine: -1,
              totalLines: j - i + 1,
              nonEmptyLines: 0
            };
          }
        }
        
        if (bodyStartLine === -1) {
          console.error(`[JavaParser] 未找到方法体开始`);
          return null;
        }
        
        // 计算大括号平衡以找到方法结束
        braceCount = 0;
        let bodyEndLine = -1;
        let nonEmptyLineCount = 0;
        
        for (let j = bodyStartLine; j < lines.length; j++) {
          const currentLine = lines[j];
          const trimmedLine = currentLine.trim();
          
          // 计算非空行
          if (trimmedLine.length > 0 && !trimmedLine.startsWith('//')) {
            nonEmptyLineCount++;
          }
          
          // 移除字符串和注释中的大括号
          const cleanedLine = this.removeStringAndCommentContent(currentLine);
          
          for (const char of cleanedLine) {
            if (char === '{') {
              braceCount++;
            } else if (char === '}') {
              braceCount--;
              if (braceCount === 0) {
                bodyEndLine = j;
                break;
              }
            }
          }
          
          if (braceCount === 0 && bodyEndLine !== -1) {
            break;
          }
        }
        
        if (bodyEndLine === -1) {
          console.error(`[JavaParser] 未找到方法结束`);
          return null;
        }
        
        const result = {
          startLine: i + 1,
          endLine: bodyEndLine + 1,
          bodyStartLine: bodyStartLine + 1,
          bodyEndLine: bodyEndLine + 1,
          totalLines: bodyEndLine - i + 1,
          nonEmptyLines: nonEmptyLineCount
        };
        
        console.error(`[JavaParser] 方法 ${methodName} 边界: ${JSON.stringify(result)}`);
        return result;
      }
      
      // 如果精确匹配失败，尝试更宽松的匹配 - 只要包含方法名和括号
      const simplePattern = new RegExp(`\\b${methodName}\\s*\\(`);
      if (simplePattern.test(line)) {
        // 检查是否是方法声明而不是调用
        const beforeMethod = line.substring(0, line.indexOf(methodName));
        if (beforeMethod.includes('=') || beforeMethod.includes('.') || beforeMethod.includes('new')) {
          continue; // 这是方法调用，不是声明
        }
        
        console.error(`[JavaParser] 使用简单匹配找到方法 ${methodName} 在第 ${i + 1} 行`);
        
        // 找到方法签名的完整部分（可能跨多行）
        let signatureEndLine = i;
        let parenCount = 0;
        let foundOpenParen = false;
        
        // 查找完整的方法签名
        for (let j = i; j < lines.length; j++) {
          const currentLine = lines[j];
          for (const char of currentLine) {
            if (char === '(') {
              parenCount++;
              foundOpenParen = true;
            } else if (char === ')') {
              parenCount--;
              if (foundOpenParen && parenCount === 0) {
                signatureEndLine = j;
                break;
              }
            }
          }
          if (foundOpenParen && parenCount === 0) break;
        }
        
        // 查找方法体的开始（第一个{）
        let bodyStartLine = -1;
        let braceCount = 0;
        for (let j = signatureEndLine; j < lines.length; j++) {
          if (lines[j].includes('{')) {
            bodyStartLine = j;
            break;
          }
          // 如果遇到分号，说明是抽象方法
          if (lines[j].includes(';')) {
            return {
              startLine: i + 1,
              endLine: j + 1,
              bodyStartLine: -1,
              bodyEndLine: -1,
              totalLines: j - i + 1,
              nonEmptyLines: 0
            };
          }
        }
        
        if (bodyStartLine === -1) {
          console.error(`[JavaParser] 未找到方法体开始`);
          return null;
        }
        
        // 计算大括号平衡以找到方法结束
        braceCount = 0;
        let bodyEndLine = -1;
        let nonEmptyLineCount = 0;
        
        for (let j = bodyStartLine; j < lines.length; j++) {
          const currentLine = lines[j];
          const trimmedLine = currentLine.trim();
          
          // 计算非空行
          if (trimmedLine.length > 0 && !trimmedLine.startsWith('//')) {
            nonEmptyLineCount++;
          }
          
          // 移除字符串和注释中的大括号
          const cleanedLine = this.removeStringAndCommentContent(currentLine);
          
          for (const char of cleanedLine) {
            if (char === '{') {
              braceCount++;
            } else if (char === '}') {
              braceCount--;
              if (braceCount === 0) {
                bodyEndLine = j;
                break;
              }
            }
          }
          
          if (braceCount === 0 && bodyEndLine !== -1) {
            break;
          }
        }
        
        if (bodyEndLine === -1) {
          console.error(`[JavaParser] 未找到方法结束`);
          return null;
        }
        
        const result = {
          startLine: i + 1,
          endLine: bodyEndLine + 1,
          bodyStartLine: bodyStartLine + 1,
          bodyEndLine: bodyEndLine + 1,
          totalLines: bodyEndLine - i + 1,
          nonEmptyLines: nonEmptyLineCount
        };
        
        console.error(`[JavaParser] 方法 ${methodName} 边界: ${JSON.stringify(result)}`);
        return result;
      }
    }
    
    console.error(`[JavaParser] 未找到方法: ${methodName}`);
    return null;
  }
  
  /**
   * 分析代码块中的变量依赖关系
   */
  static analyzeVariableDependencies(
    fullContent: string, 
    extractStartLine: number, 
    extractEndLine: number
  ): {
    declaredBefore: Map<string, { type: string, line: number }>,
    declaredInside: Map<string, { type: string, line: number }>,
    usedInside: Set<string>,
    usedAfter: Map<string, Set<number>>,
    parameters: Map<string, string>,
    returnNeeded: Map<string, string>
  } {
    const lines = fullContent.split('\n');
    const result = {
      declaredBefore: new Map<string, { type: string, line: number }>(),
      declaredInside: new Map<string, { type: string, line: number }>(),
      usedInside: new Set<string>(),
      usedAfter: new Map<string, Set<number>>(),
      parameters: new Map<string, string>(),
      returnNeeded: new Map<string, string>()
    };
    
    // 查找方法边界
    let methodStartLine = 0;
    let methodEndLine = lines.length;
    
    // 向上查找方法开始
    for (let i = extractStartLine - 2; i >= 0; i--) {
      if (this.isMethodDeclaration(lines[i])) {
        methodStartLine = i;
        break;
      }
    }
    
    // 向下查找方法结束
    let braceCount = 0;
    let foundFirstBrace = false;
    for (let i = methodStartLine; i < lines.length; i++) {
      const cleanedLine = this.removeStringAndCommentContent(lines[i]);
      for (const char of cleanedLine) {
        if (char === '{') {
          braceCount++;
          foundFirstBrace = true;
        } else if (char === '}') {
          braceCount--;
          if (foundFirstBrace && braceCount === 0) {
            methodEndLine = i;
            break;
          }
        }
      }
      if (foundFirstBrace && braceCount === 0) break;
    }
    
    // 1. 收集提取代码之前声明的变量
    for (let i = methodStartLine; i < extractStartLine - 1; i++) {
      const declarations = this.extractVariableDeclarations(lines[i]);
      for (const decl of declarations) {
        result.declaredBefore.set(decl.name, { type: decl.type, line: i + 1 });
      }
    }
    
    // 2. 收集提取代码内部声明的变量
    for (let i = extractStartLine - 1; i < extractEndLine; i++) {
      const declarations = this.extractVariableDeclarations(lines[i]);
      for (const decl of declarations) {
        result.declaredInside.set(decl.name, { type: decl.type, line: i + 1 });
      }
    }
    
    // 3. 收集提取代码内部使用的变量
    for (let i = extractStartLine - 1; i < extractEndLine; i++) {
      const usedVars = this.extractUsedVariables(lines[i]);
      for (const varName of usedVars) {
        result.usedInside.add(varName);
      }
    }
    
    // 4. 收集提取代码之后使用的变量
    for (let i = extractEndLine; i <= methodEndLine; i++) {
      const usedVars = this.extractUsedVariables(lines[i]);
      for (const varName of usedVars) {
        // 如果这个变量在提取代码内部声明
        if (result.declaredInside.has(varName)) {
          if (!result.usedAfter.has(varName)) {
            result.usedAfter.set(varName, new Set());
          }
          result.usedAfter.get(varName)!.add(i + 1);
        }
      }
    }
    
    // 5. 确定需要作为参数传递的变量
    for (const varName of result.usedInside) {
      if (!result.declaredInside.has(varName) && result.declaredBefore.has(varName)) {
        const varInfo = result.declaredBefore.get(varName)!;
        result.parameters.set(varName, varInfo.type);
      }
    }
    
    // 6. 确定需要返回的变量
    for (const [varName, usageLines] of result.usedAfter) {
      const varInfo = result.declaredInside.get(varName)!;
      result.returnNeeded.set(varName, varInfo.type);
    }
    
    
    return result;
  }
  
  /**
   * 移除字符串和注释内容
   */
  private static removeStringAndCommentContent(line: string): string {
    let result = '';
    let inString = false;
    let inChar = false;
    let stringChar = '';
    
    for (let i = 0; i < line.length; i++) {
      const char = line[i];
      const nextChar = line[i + 1];
      
      // 处理注释
      if (!inString && !inChar && char === '/' && nextChar === '/') {
        break; // 行注释，忽略后续内容
      }
      
      // 处理字符串
      if (!inChar && (char === '"' || char === "'")) {
        if (!inString) {
          inString = true;
          stringChar = char;
        } else if (char === stringChar && line[i - 1] !== '\\') {
          inString = false;
        }
        result += ' '; // 用空格替换
        continue;
      }
      
      if (!inString && !inChar) {
        result += char;
      } else {
        result += ' '; // 用空格替换
      }
    }
    
    return result;
  }
  
  /**
   * 检查是否是方法声明
   */
  private static isMethodDeclaration(line: string): boolean {
    const patterns = [
      /^\s*(?:public|private|protected)\s+(?:static\s+)?(?:final\s+)?(?:\w+(?:<[^>]+>)?)\s+\w+\s*\(/,
      /^\s*(?:\w+(?:<[^>]+>)?)\s+\w+\s*\(/ // 包内可见方法
    ];
    
    return patterns.some(pattern => pattern.test(line));
  }
  
  /**
   * 提取变量声明
   */
  private static extractVariableDeclarations(line: string): Array<{ name: string, type: string }> {
    const declarations: Array<{ name: string, type: string }> = [];
    
    // 匹配变量声明模式
    const patterns = [
      // Type varName = value;
      /\b(\w+(?:<[^>]+>)?(?:\[\])?)\s+(\w+)\s*=\s*[^;]+;/g,
      // Type varName;
      /\b(\w+(?:<[^>]+>)?(?:\[\])?)\s+(\w+)\s*;/g,
      // for (Type var : collection)
      /for\s*\(\s*(\w+(?:<[^>]+>)?)\s+(\w+)\s*:/g,
      // catch (Exception e)
      /catch\s*\(\s*(\w+)\s+(\w+)\s*\)/g
    ];
    
    for (const pattern of patterns) {
      let match;
      pattern.lastIndex = 0; // 重置正则表达式
      while ((match = pattern.exec(line)) !== null) {
        const type = match[1];
        const name = match[2];
        // 过滤掉非类型关键字，但允许基本类型
        const allowedTypes = new Set(['int', 'long', 'short', 'byte', 'float', 'double', 'char', 'boolean']);
        if ((allowedTypes.has(type) || !this.isJavaKeyword(type)) && !this.isJavaKeyword(name)) {
          declarations.push({ name, type });
        }
      }
    }
    
    return declarations;
  }
  
  /**
   * 提取使用的变量
   */
  private static extractUsedVariables(line: string): Set<string> {
    const used = new Set<string>();
    const cleanedLine = this.removeStringAndCommentContent(line);
    
    // 匹配变量使用的模式
    const varPattern = /\b([a-zA-Z_]\w*)\b/g;
    let match;
    
    while ((match = varPattern.exec(cleanedLine)) !== null) {
      const varName = match[1];
      // 过滤掉Java关键字、类名（首字母大写）、方法调用
      if (!this.isJavaKeyword(varName) && 
          !/^[A-Z]/.test(varName) && // 不是类名
          !cleanedLine.includes(`${varName}(`)) { // 不是方法调用
        used.add(varName);
      }
    }
    
    return used;
  }
  
  /**
   * 检查是否是Java关键字
   */
  private static isJavaKeyword(word: string): boolean {
    const keywords = new Set([
      'abstract', 'assert', 'boolean', 'break', 'byte', 'case', 'catch', 'char',
      'class', 'const', 'continue', 'default', 'do', 'double', 'else', 'enum',
      'extends', 'final', 'finally', 'float', 'for', 'goto', 'if', 'implements',
      'import', 'instanceof', 'int', 'interface', 'long', 'native', 'new', 'null',
      'package', 'private', 'protected', 'public', 'return', 'short', 'static',
      'strictfp', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws',
      'transient', 'try', 'void', 'volatile', 'while', 'true', 'false'
    ]);
    return keywords.has(word);
  }
}